
/**
 * 
 * 猜数字
 * 
 * 题目描述

一个人设定一组四码的数字作为谜底，另一方猜。

每猜一个数，出数者就要根据这个数字给出提示，提示以XAYB形式呈现，直到猜中位置。

其中X表示位置正确的数的个数（数字正确且位置正确），而Y表示数字正确而位置不对的数的个数。

例如，当谜底为8123，而猜谜者猜1052时，出题者必须提示0A2B。

例如，当谜底为5637，而猜谜者才4931时，出题者必须提示1A0B。

当前已知N组猜谜者猜的数字与提示，如果答案确定，请输出答案，不确定则输出NA。

输入描述
第一行输入一个正整数，0＜N ＜ 100。

接下来N行，每一行包含一个猜测的数字与提示结果。

输出描述
输出最后的答案，答案不确定则输出NA。

用例
输入	6
4815 1A1B
5716 0A1B
7842 0A1B
4901 0A0B
8585 3A0B
8555 2A1B
输出	3585
说明	无


 */

import java.util.ArrayList;
import java.util.Scanner;

/**
  * 
  题目解析
我的解题思路是：

暴力枚举所有可能的谜底，即0000~9999，然后用每一个谜底去过输入的猜测。

我们假设某个谜底 和 输入的猜测数字 产生的猜测提示是real_result，而输入中猜测数字对应的猜测提示是expect_result，如果real_result == expect_result，那么说明说明当前谜底符合当前猜测数字的要求。

如果某个谜底，可以符合所有猜测数字的要求，那么该谜底就是一个可用谜底。

如果，暴力枚举出来的所有谜底中，只有一个可用谜底，那么该谜底就是题解。否则本题无解，返回NA。

优化思路：

上面算法可能会超时，原因就是我们需要验证0000~9999这一万个可能的谜底，而每个可能的谜底有需要验证最多100个输入的猜测数字。

因此，我们可以做一些剪枝优化，比如题目用例输入中有一行：

4901 0A0B
这行的含义其实是：真正的谜底的四个数字不能取4，9，0，1这些。

再比如：

5716 0A1B
7842 0A1B
4901 0A0B
上面三行中，都是0A，即每一位上的数字都不是真正谜底的该位置的数字。

比如：5716 0A1B

即：真正的谜底，第一位不可能是5，第二位不可能是7，第三位不可能是1，第四位不可能是6

那么真正的谜底，第一位只能从非5数种选，第二位只能从非7数中选.......

这样的话，就做到了剪枝优化，即四码谜底的每一位数不需要从0~9中选，而是可以从更小的范围内选。

目前，我这边制作了0A，以及0A0B的剪枝处理，其他情况比如：

0A0B  0A1B  0A2B  0A3B  0A4B
1A0B  1A1B  1A2B  1A3B
2A0B  2A1B  2A2B
3A0B  3A1B
4A0B

可以视实际机试时间限制要求选做。

遍历 0 - 9999
每个数字 构建成四位数，不足位则补 0 String.format("%04d", i)

把这个数去和 猜测的 4 位数比较 得到的 猜测结果全部对上 则为正确答案

把这个数去和 猜测的 4 位数比较  逻辑

计算 数字和位置都一样的 XA   ---   guess.charAt(i) == answer.charAt(i)

数字一样位置不一样的  YB      构建不符合 A 的 2 个数据结合，里面有一样的值的个数

组合
  */

public class 猜数字 {
    
    public static void main(String[] args) {
        try{

            Scanner scanner = new Scanner(System.in);

            //m
            int n = scanner.nextInt();
            //猜测和结果数组
            String[] guessArr = new String[n];
            String[] resultArr = new String[n];
            for(int i=0; i<n; i++){
                guessArr[i] = scanner.next();
                resultArr[i] = scanner.next();
            }

            ArrayList<String> answers = new ArrayList<>();

            for (int num = 0; num <= 9999; num++) {

                String answer = String.format("%04d", num); // 补足前导0, 使num变为四位, 当作一个可能的answer

                // 和每一个guess比较, 对比结果是否满足result
                int i = 0;
                for (; i < guessArr.length; i++) {
                    if (!resultArr[i].equals(handleGuess(answer, guessArr[i]))) {
                        break;
                    }
                }
 
                // 只有全部满足时, 当前answer才是一个符合要求的解
                if (i == guessArr.length) {
                    answers.add(answer);
                }

            }

            if (answers.size() != 1) {
                // 不存在唯一解，则答案不确定
                System.out.println("NA");
            } else {
                System.out.println(answers.get(0));
            }


        }catch(Exception e){
        
            e.printStackTrace();
        }
    }

    private static String handleGuess(String answer, String guess){


        int X = 0;
        int Y = 0;
 
        ArrayList<Character> guessList = new ArrayList<>();
        ArrayList<Character> answerList = new ArrayList<>();
 
        for (int i = 0; i < 4; i++) {
            if (guess.charAt(i) == answer.charAt(i)) {
                X++; // 数字正确且位置正确
            } else {
                guessList.add(guess.charAt(i));
                answerList.add(answer.charAt(i));
            }
        }
 
        for (Character c : guessList) {
            if (answerList.remove(c)) {
                Y++; // 数字正确而位置不对的数的个数
            }
        }
 
        return X + "A" + Y + "B";

    }
}
